package controllers;

import java.lang.reflect.Constructor;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

import models.ProductType;

import play.Logger;
import play.data.binding.Binder;
import play.db.Model;
import play.db.jpa.JPABase;
import play.exceptions.TemplateNotFoundException;
import play.i18n.Messages;
import play.mvc.Before;
import play.mvc.Catch;
import play.mvc.Router;
import play.mvc.With;
import play.mvc.Router.ActionDefinition;
import play.mvc.Router.Route;
import play.utils.Properties;
import controllers.CRUD;
import controllers.Secure;
import controllers.CRUD.ObjectType;
import exceptions.DuplicateUrlKeyException;

@With(Secure.class)
public class ProductTypes extends CRUD {

	@Catch(DuplicateUrlKeyException.class)
	public static void promptUrlKeyException(Throwable throwable) throws Exception{
		
        ObjectType type = ObjectType.get(getControllerClass());
        notFoundIfNull(type);
        Constructor<?> constructor = type.entityClass.getDeclaredConstructor();
        constructor.setAccessible(true);
        Model object = (Model) constructor.newInstance();
        Binder.bindBean(params.getRootParamNode(), "object", object);
        renderArgs.put("error",play.i18n.Messages.get("crud.hasErrors"));
        validation.addError("object.urlKey", "URLKey重复");

        if("create".equals(request.actionMethod)){
        	try {
                render(request.controller.replace(".", "/") + "/blank.html", type, object);
            } catch (TemplateNotFoundException e) {
                render("CRUD/blank.html", type, object);
            }
        }else if("save".equals(request.actionMethod)){
        	try {
                render(request.controller.replace(".", "/") + "/show.html", type, object);
            } catch (TemplateNotFoundException e) {
                render("CRUD/show.html", type, object);
            }
        }
    }

	@Before(only={"create","save"})
	static void setModifier(){
		Logger.debug("moethod %s", request.actionMethod);
		if("create".equals(request.actionMethod)){
			params.put("object.creator.username", Security.connected());
			params.put("object.modifier.username", Security.connected());
		}else if("save".equals(request.actionMethod)){
			params.put("object.modifier.username", Security.connected());
		}
	
	}
	
	@Before(only={"blank","create"})
	static void setProductTypeId(){
		String parent = params.get("object.parent.id");
		routeArgs.put("parent", parent);
	}
	
	public static void list(Long parent,int page, String searchFields, String orderBy, String order) { 
		long rootId = ProductType.getRootId();
		ObjectType type = ObjectType.get(getControllerClass());
		if(parent==null){
			parent = ProductType.getRootId();
		}
		ProductType tmp = ProductType.findById(parent);
		List<ProductType> parents = new ArrayList<ProductType>();
		while(tmp!=null && tmp.id!=rootId){
			parents.add(tmp);
			tmp = tmp.parent;
		}
		Collections.reverse(parents);
		
        List<Object> objects = ProductType.find("from ProductType where parent.id=? order by priority", parent).fetch(page, getPageSize());
        long count = ProductType.count("parent.id",parent);
        
        ProductType root = ProductType.findById(rootId);
        render(type, objects, count, page,parent,parents,rootId,root);
    }
	
	public static void blank(Long parent) throws Exception {
        ObjectType type = ObjectType.get(getControllerClass());
        notFoundIfNull(type);
        ProductType parentObj = ProductType.findById(parent);
        ProductType object = new ProductType();
        object.parent = parentObj;
        
        try {
            render(type, object,parent);
        } catch (TemplateNotFoundException e) {
            render("CRUD/blank.html", type, object);
        }
    }
	
	public static void jsonTree(final String callback){
		long rootId = ProductType.getRootId();
		ProductType root = ProductType.findById(rootId);
		renderJSON(root,new JsonSerializer<ProductType>(){
			
			public JsonElement serialize(ProductType productType, Type arg1,
					JsonSerializationContext context) {
				return toJson(productType.children);
			}
			
			private JsonArray toJson(List<ProductType> children){
				JsonArray objects = new JsonArray();
				if(children!=null){
					for (ProductType productType : children) {
						JsonObject object = new JsonObject();
						object.addProperty("text", "<a href=\"javascript:"+callback+"('"+productType.id+"','"+productType.name+"')\">"+productType.name+"</a>");
						if(productType.children!=null && productType.children.size()>0){
							object.add("children", toJson(productType.children));
						}
						objects.add(object);
					}
				}
				return objects;
			}

		});
		
	}
		
}
